/* 单元格点击：
1 获取到所有的单元格列表。
2 遍历单元格列表，给每个单元格添加点击事件。
3 给当前被点击的单元格添加类名 x。
(优化)（1）防止单元格重复点击，在添加事件时，使用once属性，让单元格只能被点击一次。
（2）使用函数声明形式的事件处理程序（代码多了后，结构更清晰）

切换玩家：
1 创建一个存储当前玩家的变量（currentPlayer）,默认值值为：x
2 将添加给单元格时 写死的类名x，替换为变量（currentPlayer）
3 切换到另一个玩家：在添加类名后，根据当前下的玩家，切换另外一个玩家。
4 移除上游戏面板的提示（x 或者 o）添加下一个玩家对应的类名

currentPlayer:（o0）
枚举:只能是几个固定中的一个

封装判赢函数：
1 声明函数checkWin,指定参数player,类型注解为Player枚举。
2 指定返回值：true或者false
3 添加类名后（下棋后），调用函数checkWin,拿到函数返回值
4 判断函数返回值是否为true,如果是，说明当前玩家获胜。
 */
enum Player{
    X='x',
    O='o'}
// 判断数组
let winArr = [
        [0, 1, 2],[3, 4, 5],[6, 7, 8],     // 横
        [0, 3, 6],[1, 4, 7],[2, 5, 8],     // 竖
        [0, 4, 8],[2, 4, 6],               // 斜
]

// 单元格列表
let cells = document.querySelectorAll('.cell')
// console.log(cells)
// 游戏面板
let gameBord = document.querySelector('#bord')
// console.log(gameBord)
//  let currentPlayer:Player = Player.X
// 当前玩家
 let currentPlayer:Player
//  记录已下棋的次数
let steps:number
 
let message = document.querySelector('#message') as HTMLDivElement
let winner = document.querySelector('#winner') as HTMLParagraphElement
let restart = document.querySelector('#restart') as HTMLButtonElement


// 优化：将第一次游戏看成是在重新开始游戏
restart.addEventListener('click',startGame)
// 调用该函数来初始化游戏数据 开始游戏
startGame()
function startGame(){
    // console.log('click')
    message.style.display='none'
    // 重置下棋次数
    steps = 0
    // 重置默认玩家为x 重置下棋提示为x
    currentPlayer = Player.X
    gameBord.classList.remove(Player.X,Player.O)
    gameBord.classList.add(Player.X)

    cells.forEach(function(item){
        let cell = item as HTMLDivElement
        // 清空棋盘
        cell.classList.remove(Player.X,Player.O)
        // 移除单元格点击事件 重新给单元格绑定点击事件
        cell.removeEventListener('click',clickCell)
        cell.addEventListener('click',clickCell,{once:true})
    })

}

// 给单元格绑定点击事件
// cells.forEach(function(item){
//     let cell = item as HTMLDivElement
//     // console.log(item)
//     cell.addEventListener('click',clickCell,{once:true})
// })

// 棋盘中单元格的click事件处理程序
function clickCell(event:MouseEvent){
    // console.log('click',event.target)
    let target = event.target as HTMLDivElement
    target.classList.add(currentPlayer)

      steps++

    // 调用判赢函数判断是否获胜
    let isWin = checkWin(currentPlayer)
    if(isWin){
        message.style.display='block'
        winner.innerHTML=currentPlayer+' 赢了'
        // console.log('当前玩家获胜了',currentPlayer)

        return
    }

    // 判断平局
    if(steps===9){
       message.style.display='block'
       winner.innerHTML='平局'
       return
    }
    

    // 根据当前下的玩家，切换另外一个玩家o
    currentPlayer = currentPlayer === Player.X?Player.O:Player.X
    // 提示
    gameBord.classList.remove(Player.X,Player.O)
    gameBord.classList.add(currentPlayer)
}

// 判赢函数
function checkWin(player:Player){
    // console.log('参数',player)
    // return true
    // 数组some方法：遍历数组时可终止 2方法返回值为true或者false

    // 优化：
    // 1去掉中间变量isWin cell1 cell2 cell3
    // 2封装函数hasClass 判断DOM元素是否包含某个类名

    return winArr.some(function(item){
    // 获取到每种获胜情况对应的3个单元格元素
    // 1 先拿到每种获胜情况的三个索引
       // console.log(item)
       let cellIndex1 = item[0]
       let cellIndex2 = item[1]
       let cellIndex3 = item[2]
       // console.log(cellIndex1,cellIndex2,cellIndex3)
    // 2 通过这三个索引从cells中获取到对应的单元格元素
        // let cell1 = cells[cellIndex1]
        // let cell2 = cells[cellIndex2]
        // let cell3 = cells[cellIndex3]
        // console.log(cell1,cell2,cell3)
    // 3 判断这3个单元格元素是否同时包含当前玩家的类名
    // 重点：
    // （1）元素是否包含类名classList.contains()
    // （2）同时包含（第一个包含 并且 第二个包含 并且第三个包含）逻辑与 &&
    if(
        // cells[cellIndex1].classList.contains(player)&&
        // cells[cellIndex2].classList.contains(player)&&
        // cells[cellIndex3].classList.contains(player)
        hasClass(cells[cellIndex1],player)&&
        hasClass(cells[cellIndex2],player)&&
        hasClass(cells[cellIndex3],player)
    ){
        return true
    }
    return false

    })
    
}

    // 2封装函数hasClass 判断DOM元素是否包含某个类名
    function hasClass(el:Element,name:string){
        return el.classList.contains(name)
    }